﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using YArchitech.Revit.RevitExtension;
using YJKRevitCode.ElmentSearchUtility.LinkDocumentSuite;
using YJKRGeometry;
using SectionSignAndFilled.StairsRoomSection.DataDefine;
using SectionSignAndFilled.StairsRoomSection.Kit;
using SectionSignAndFilled.StairsRoomSection.Kit.Xdata;

namespace SectionSignAndFilled.StairsRoomSection.SignElems
{
	public class HorizontalSign
	{
		public HorizontalSign(SectionViewData sectionData, List<BaseLinkDocumentResultBean> lstGrid, List<BaseLinkDocumentResultBean> lstWall)
		{
			this.m_viewData = sectionData.clone();
			this.m_doc = sectionData.SectionView.Document;
			this.m_SecLine = sectionData.m_SecLine;
			this.m_lstGrid = new List<BaseLinkDocumentResultBean>();
			this.m_lstGrid.AddRange(lstGrid);
			this.m_lstWall = new List<BaseLinkDocumentResultBean>();
			this.m_lstWall.AddRange(lstWall);
		}

		public bool Sign()
		{
			if (this.m_lstGrid.Count == 0)
			{
				return true;
			}
			bool result;
			try
			{
				if (!this.GetBasePt())
				{
					result = false;
				}
				else
				{
					bool flag = this.SignGrid();
					if (this.m_lstWall.Count > 0)
					{
						flag = this.SignDetail();
					}
					if (this.m_lstNewGrid.Count > 0)
					{
						this.m_doc.Delete(this.m_lstNewGrid);
					}
					result = true;
				}
			}
			catch (Exception)
			{
				if (this.m_lstNewGrid.Count > 0)
				{
					this.m_doc.Delete(this.m_lstNewGrid);
				}
				result = false;
			}
			return result;
		}

		private bool GetBasePt()
		{
			this.filterGrid();
			if (this.m_lstGrid.Count == 0)
			{
				return false;
			}
			this.m_lstGrid.Sort(new GridComparision(this.m_viewData));
			Element useElement = this.m_lstGrid[0].UseElement;
			Curve gridCurveOnView = SignCommon.GetGridCurveOnView(this.m_lstGrid[0], this.m_viewData);
			if (gridCurveOnView == null)
			{
				return false;
			}
			XYZ endPoint = gridCurveOnView.GetEndPoint(0);
			XYZ endPoint2 = gridCurveOnView.GetEndPoint(1);
			XYZ zero = XYZ.Zero;
			if (endPoint.Z > endPoint2.Z)
			{
				this.m_BasePt = endPoint2;
			}
			else
			{
				this.m_BasePt = endPoint;
			}
			this.m_BasePt = new XYZ(this.m_BasePt.X, this.m_BasePt.Y, this.m_viewData.DBottomElev);
			return true;
		}

		private void filterGrid()
		{
			new List<BaseLinkDocumentResultBean>();
			Dictionary<int, List<BaseLinkDocumentResultBean>> dictionary = new Dictionary<int, List<BaseLinkDocumentResultBean>>();
			foreach (BaseLinkDocumentResultBean baseLinkDocumentResultBean in this.m_lstGrid)
			{
				int linkeInstanceId = baseLinkDocumentResultBean.LinkeInstanceId;
				if (dictionary.ContainsKey(linkeInstanceId))
				{
					dictionary[linkeInstanceId].Add(baseLinkDocumentResultBean);
				}
				else
				{
					dictionary.Add(linkeInstanceId, new List<BaseLinkDocumentResultBean>
					{
						baseLinkDocumentResultBean
					});
				}
			}
			List<BaseLinkDocumentResultBean> list = new List<BaseLinkDocumentResultBean>();
			foreach (KeyValuePair<int, List<BaseLinkDocumentResultBean>> keyValuePair in dictionary)
			{
				if (keyValuePair.Key == -1)
				{
					list.AddRange(keyValuePair.Value);
				}
				else
				{
					List<ElementId> list2 = new List<ElementId>();
					bool flag = CommonFun.CopyElementsFromLinkDocToCurrentDoc(this.m_doc, keyValuePair.Value, ref list2);
					if (flag)
					{
						this.m_lstNewGrid.AddRange(list2);
						foreach (ElementId elementId in list2)
						{
							BaseLinkDocumentResultBean item = new BaseLinkDocumentResultBean(this.m_doc.GetElement(elementId), null, null);
							list.Add(item);
						}
					}
				}
			}
			this.m_lstGrid.Clear();
			foreach (BaseLinkDocumentResultBean baseLinkDocumentResultBean2 in list)
			{
				Curve gridCurveOnView = SignCommon.GetGridCurveOnView(baseLinkDocumentResultBean2, this.m_viewData);
				if (gridCurveOnView != null)
				{
					this.m_lstGrid.Add(baseLinkDocumentResultBean2);
				}
			}
		}

		public bool SignDetail()
		{
			XYZ xyz = this.m_BasePt + (SignCommon.m_dFirstBaseLineInterval + SignCommon.m_dBaseLineInterval) * this.m_doc.ActiveView.UpDirection;
			Line line = Line.CreateUnbound(xyz, this.m_doc.ActiveView.RightDirection);
			List<XYZ> list = new List<XYZ>();
			foreach (BaseLinkDocumentResultBean bean in this.m_lstWall)
			{
				this.GetWallSignPt(bean, ref list);
			}
			foreach (BaseLinkDocumentResultBean bean2 in this.m_lstGrid)
			{
				Curve gridCurveOnView = SignCommon.GetGridCurveOnView(bean2, this.m_viewData);
				XYZ endPoint = gridCurveOnView.GetEndPoint(0);
				list.Add(endPoint);
			}
			List<XYZ> list2 = new List<XYZ>();
			foreach (XYZ xyz2 in list)
			{
				list2.Add(line.Project(xyz2).XYZPoint);
			}
			list = list2;
            //from e in list
            //orderby this.m_SecLine.Project(e).Parameter
            //select e;
			ReferenceArray referenceArray = new ReferenceArray();
			foreach (XYZ xyz3 in list)
			{
				Curve curve = Line.CreateBound(xyz3 + 0.01 * this.m_doc.ActiveView.UpDirection, xyz3 + 0.02 * this.m_doc.ActiveView.UpDirection);
				DetailCurve detailCurve = this.m_doc.Create.NewDetailCurve(this.m_doc.ActiveView, curve);
				if (detailCurve != null)
				{
					SignXdataForReference.WriteSignComment(detailCurve, this.m_doc.ActiveView.Id);
				}
				referenceArray.Append(new Reference(detailCurve));
			}
			ElementId dimSymbol = SignCommon.GetDimSymbol(this.m_doc);
			Dimension dimension = this.m_doc.Create.NewDimension(this.m_doc.ActiveView, line, referenceArray, this.m_doc.GetElement(dimSymbol) as DimensionType);
			if (dimension != null)
			{
				SignXdataForReference.WriteSignComment(dimension, this.m_doc.ActiveView.Id);
				RevitDimensionExtension.ResetDimTextPos(dimension);
			}
			return true;
		}

		public bool SignGrid()
		{
			if (this.m_lstGrid.Count<BaseLinkDocumentResultBean>() < 2)
			{
				return true;
			}
			XYZ xyz = this.m_BasePt + SignCommon.m_dFirstBaseLineInterval * this.m_doc.ActiveView.UpDirection;
			Line line = Line.CreateUnbound(xyz, this.m_doc.ActiveView.RightDirection);
			ReferenceArray referenceArray = new ReferenceArray();
			foreach (BaseLinkDocumentResultBean bean in this.m_lstGrid)
			{
				Curve gridCurveOnView = SignCommon.GetGridCurveOnView(bean, this.m_viewData);
				XYZ endPoint = gridCurveOnView.GetEndPoint(0);
				XYZ endPoint2 = gridCurveOnView.GetEndPoint(1);
				double val = line.Distance(endPoint);
				double val2 = line.Distance(endPoint2);
				XYZ xyz2;
				if (Geometry.LessThan(val, val2))
				{
					xyz2 = endPoint;
				}
				else
				{
					xyz2 = endPoint2;
				}
				xyz2 = line.Project(xyz2).XYZPoint;
				Curve curve = Line.CreateBound(xyz2 + 0.01 * this.m_doc.ActiveView.UpDirection, xyz2 + 0.02 * this.m_doc.ActiveView.UpDirection);
				DetailCurve detailCurve = this.m_doc.Create.NewDetailCurve(this.m_doc.ActiveView, curve);
				this.m_doc.Regenerate();
				if (detailCurve != null)
				{
					SignXdataForReference.WriteSignComment(detailCurve, this.m_doc.ActiveView.Id);
				}
				referenceArray.Append(new Reference(detailCurve));
			}
			ElementId dimSymbol = SignCommon.GetDimSymbol(this.m_doc);
			Dimension dimension = this.m_doc.Create.NewDimension(this.m_doc.ActiveView, line, referenceArray, this.m_doc.GetElement(dimSymbol) as DimensionType);
			if (dimension != null)
			{
				SignXdataForReference.WriteSignComment(dimension, this.m_doc.ActiveView.Id);
			}
			return true;
		}

		private bool GetWallSignPt(BaseLinkDocumentResultBean bean, ref List<XYZ> lstPt)
		{
			Wall wall = bean.UseElement as Wall;
			Transform totalTransform = bean.GetTotalTransform();
			XYZ xyz = null;
			SignCommon.GetWallLocationIntersectionSeclinePt(totalTransform, wall, this.m_SecLine, ref xyz);
			XYZ orientation = wall.Orientation;
			XYZ xyz2 = orientation.Normalize().Negate();
			xyz2 = totalTransform.OfVector(xyz2);
			XYZ item = xyz + xyz2 * wall.Width / 2.0;
			XYZ item2 = xyz + xyz2 * -wall.Width / 2.0;
			lstPt.Add(item);
			lstPt.Add(item2);
			return true;
		}

		private Document m_doc;

		private Line m_SecLine;

		private SectionViewData m_viewData;

		private List<BaseLinkDocumentResultBean> m_lstGrid;

		private List<BaseLinkDocumentResultBean> m_lstWall;

		private XYZ m_BasePt;

		private List<ElementId> m_lstNewGrid = new List<ElementId>();
	}
}
